三次握手与四次挥手在具体函数上的体现 | 您所在的位置:网站首页 › send 怎么念 › 三次握手与四次挥手在具体函数上的体现 |
文章目录
三次握手服务器和客户端分别是发生在哪个函数**知识点:**
数据传输阶段`send`返回整数不一定代表发送成功为什么会发生发送不成功?传输过程中的粘包分包问题
网络断开连接简单总结各个函数的作用客户端
网络编程
API组成
服务端API客户端APIsocket()socket()bind()bind() [optional]listen()accept()connect()recv()send()send()close()recv()close()shutdown()
三次握手服务器和客户端分别是发生在哪个函数
服务器调用listen使服务器处于LISTEN状态,等待客户端请求连接 首先客户端调用connect发起第一次SYN包,然后处于**SYN_SENT状态**,此时服务端会将这个连接放进半连接队列 服务端收到SYN包以后会发送给客户端一个ACK|SYN包,此时服务端状态转移为SYN_RECV 客户端接收到服务端发来的ACK|SYN包进行解析后会在半连接队列中查找携带这个信息的节点是否存在,如果存在则move出来加入全连接队列中,并且发送ACK包给服务端,此时客户端状态转移为ESTABLISHED 服务端收到客户端的ack后也状态转移为ESTABLISHED 知识点:半连接队列与全连接队列 都是在服务端那里存在的队列backlog参数的含义 三种说法都存在 半连接队列大小两个队列大小的和全连接队列大小本机上man listen查看 defines the maximum length to which the pending connections for sockfd for sockfd may grow 代表全连接队列的大小 ddos攻击 客户端只发第一次握手,不会返回ACK,使半连接队列溢出双方都发起第一次握手可以吗 不可以,会导致连接无法正常建立 数据传输阶段 send返回整数不一定代表发送成功 send只是将数据拷贝到了内核,之后多久发送是协议栈规定的,自己不知道 为什么会发生发送不成功? 据包在传输过程中很复杂,可能对方网络很差,在某一个路由器中丢包了,数据包总是根据目的ip、port来寻找 传输过程中的粘包分包问题客户端调用send,send只将数据拷贝到协议栈里面,其他什么都不做 如何做好分包粘包 多次send会发生粘包和合包的问题 解决 应用层协议头前面加packetlen 为每一个包加上分隔符 \r\n 这两种做法有什么区别 // 先读长度,再读数据 read(tcphdr, 2); read(tcphdr->length); //or while(count length){ size = read(tcphdr->lenghth - count); count += size; } // 检测内容 read(buffer, 1024); buffer[idx] = "\r\n"; pkt = &buffer[idx + 2]; // 为了后续合包网线断了立马重启,tcp是如何检测到的 通过设计->心跳包来检测 网络断开连接不分客户端或者服务器,只分主动或者被动 首先调用close的端会将最后一次包的FIN位置为1,并且处于状态为FIN_WAIT1对端收到带有FIN的包后会返回给发送端一个ACK包,这个是立即发送的,代表我知道你不给我发数据了,之后对端状态转移为CLOSE_WAIT发送端接收到后状态转移为FIN_WAIT2之后对端在发送FIN包之前的这一段时间,它还可以给发送端发数据,当对端处理好所有数据后会发送最后的FIN包,此时状态会转移为LAST_ACK发送端接收到对端发送的FIN包之后会发送一个ACK包然后处于**TIME_WAIT状态**,过了这段时间后就处于**CLOSE状态**对端接收到ACK后连接断开,处于CLOSE状态一些面试题: 如果出现大量close_wait该怎么办(这种现象是因为recv返回0后到调用close时间太长) 把业务数据释放与网路层的(recv和close)做一个分离,把他做成异步的,就是将释放资源客户端相关做成异步,这样一来recv==0后就可以立即close(fd)了会出现双方同时调用close吗?引入closing 以某一端为例,先发fin,进入fin_wait1,然后收到对端发送的fin包而不是ack,则为两端同时关闭,直接进入closing状态为什么会有time_wait 如果laskack在传输过程中丢了,则对端会重发fin,如果没有time_wait则对应的端口会立即被释放出来,如果此时有一个应用程序连接进来刚好用到了该端口,则会直接收到fin包从而进入close_wait状态从而直接进入四次挥手为了避免最后一次ack丢失 简单总结各个函数的作用socket 文件系统分配fd,且分配一个tcbbind 绑定本地的ip、端口listen 将fd置为listen状态accept 从全连接队列中取出一个tcb(TCP control block)并分配一个fdrecv 在对应的fd里面,将对应的readbuffer读出来send 在fd对应的tcb里面将数据拷贝到sendbuffer里面close 将sendbuffer里面的最后一个包的fin位置为1回收fd 客户端bind 可选,如果不调用则随机端口,调用则指定端口connect 准备一个syn包给服务端发送过去等待三次握手完成之后connect再返回思考:这个函数有没有等待的动作,是不是个阻塞的,如果连不上,会阻塞吗 有等待的动作但不会阻塞,如果连不上则会被连接被拒绝 |
CopyRight 2018-2019 实验室设备网 版权所有 |